// cf-435d
// 题意：给定按矩形排序的n行每行m个棋子(n, m<=400)，每个棋子或者黑色或者
//       白色，将相邻的棋子（包括45度对角）的棋子连边。问里面有多少满足
//       条件的三角形。
//         1.三角形三个顶点是棋子;
//         2.每条边要么竖直要么水平要么45度斜对角;
//         3.每条边上都不能有黑色的棋子。
//
// 题解：很简单，预处理往下，往左，往右，往左下，往右下，延伸最大程度，
//       然后对于每个点可以O(n)算出个数。
//       
// run: $exec < input
#include <iostream>

int const maxn = 407;
bool bad[maxn][maxn];
int right[maxn][maxn], left[maxn][maxn], down[maxn][maxn];
int ld[maxn][maxn], rd[maxn][maxn];
int n, m;

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			char ch;
			std::cin >> ch;
			bad[i][j] = ch == '1';
		}

	// left & right
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++)
			left[i][j] = (bad[i][j] ? 0 : left[i][j - 1] + 1);
		for (int j = m; j >=1; j--)
			right[i][j] = (bad[i][j] ? 0 : right[i][j + 1] + 1);
	}
	// down
	for (int j = 1; j <= m; j++)
		for (int i = n; i >= 1; i--)
			down[i][j] = (bad[i][j] ? 0 : down[i + 1][j] + 1);
	// left down
	for (int t = 1; t <= n + m - 1; t++) {
		int j = t <= n ? 1 : (t - n);
		int i = t > n ? n : t;
		for (; i >= 1 && j <= m; i--, j++)
			ld[i][j] = (bad[i][j] ? 0 : ld[i + 1][j - 1] + 1);
	}
	// right down
	for (int t = 1; t <= n + m - 1; t++) {
		int j = t > m ? m : t;
		int i = t <= m ? n : n - t + m;
		for (; i >= 1 && j >= 1; i--, j--)
			rd[i][j] = (bad[i][j] ? 0 : rd[i + 1][j + 1] + 1);
	}

	long long ans = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			if (left[i][j]) left[i][j]--;
			if (right[i][j]) right[i][j]--;
			if (down[i][j]) down[i][j]--;
			if (ld[i][j]) ld[i][j]--;
			if (rd[i][j]) rd[i][j]--;
			for (int t = j - std::min(left[i][j], down[i][j]); t < j; t++)
				ans += rd[i][t] >= j - t;
			for (int t = j + std::min(right[i][j], down[i][j]); t > j; t--)
				ans += ld[i][t] >= t - j;

			for (int t = j - std::min(ld[i][j], down[i][j]); t < j; t++)
				ans += right[i + j - t][t] >= j - t;
			for (int t = j - std::min(ld[i][j], down[i][j]/2); t < j; t++)
				ans += rd[i + j - t][t] >= j - t;

			for (int t = j + std::min(rd[i][j], down[i][j]); t > j; t--)
				ans += left[i + t - j][t] >= t - j;
			for (int t = j + std::min(rd[i][j], down[i][j]/2); t > j; t--)
				ans += ld[i + t - j][t] >= t - j;

			for (int t = std::min(std::min(left[i][j], right[i][j]) + i, n); t > i; t--)
				ans += !bad[t][j] && ld[i][t - i + j] >= t - i && rd[i][j - (t - i)] >= t - i;
			for (int t = std::min(std::min(ld[i][j], rd[i][j]) + i, n); t > i; t--)
				ans += !bad[t][j] && left[t][t - i + j] >= 2 * (t - i);
	}
	std::cout << ans << '\n';
}

